#include <iostream>
#include <cstring>
#include <vector>

#include "TemplateStudy.cpp"
using namespace std;
#define Z_MAXLEN 100

struct PersonInfo{
     int index;
     char name[30];
     short age;
}Person[5] ={{1,"张三",23},{2,"王五",22},{3,"赵柳",35},{4,"李冰冰",53},{5,"张嘎",36}};

class CList
{
public:
     CList(){
          m_Height =0;
     }
     class CNode//嵌套类只允许在外围的类域中使用，其他类域是不可见的
     {
       friend class CList;
       private :
           int m_Tag;
       public:
           char m_Name[Z_MAXLEN];

     };
public:
    CNode m_Node;
    void setNodeName(const char *name){
         if (name !=NULL)
         {
           strcpy(m_Node.m_Name,name);
         }
         
    }
    void setNodeTag(int tag){
         m_Node.m_Tag;//由于CNode类将CList类作为自己的有元类，所以能访问到CNode的私有成员

    }

    friend int computeArea(CList &myRect);//friend 有元使得该函数能够访问CList的私有成员

protected:
    int m_Height;
    int m_Width;

};

int computeArea(CList &myRect){
     return myRect.m_Height * myRect.m_Width;

}

void swap(int &a,int &b){
     int tmp;
     tmp = a;
     a =b;
     b =tmp;

}

void print_arr(int arr[],int len){
    for (int  i = 0; i < len; i++)
    {
     cout<< arr[i]<<" ";
    }

    cout<<endl;  

}

void print_arr_refer(int (&arr)[],int len){
    for (int  i = 0; i < len; i++)
    {
     cout<< arr[i]<<" ";
    }

    cout<<endl;  

}

void print_arr_p(int *arr,int len){
    for (int  i = 0; i < len; i++)
    {
     cout<< arr[i]<<" ";
    }

    cout<<endl;  

}

//使用C++ 标准库中的std::vector等容器，这些容器可以方便地传递给函数，并且不需要显式地传递数组大小。
template <typename T> 
void print_arr_vector_const(const std::vector<T>& vec){
    cout<<"use for:"<<endl;  
    for (const auto& value:vec)
    {
     cout<< value<<" ";
    }

    cout<<endl;  
    cout<<"use iterator:"<<endl;  
    typename vector<T>::const_iterator itm = vec.begin();
    while (itm != vec.end())
    {
     cout<<*itm++<<" ";

    }
    
    cout<<endl;  

}

template <typename T> 
void print_arr_vector(std::vector<T>& vec){
    cout<<"use for:"<<endl;  
    for (const auto& value:vec)
    {
     cout<< value<<" ";
    }

    cout<<endl;  
    cout<<"use iterator:"<<endl;  
    typename vector<T>::iterator itm = vec.begin();
    while (itm != vec.end())
    {
     cout<<*itm++<<" ";

    }
    

    cout<<endl;  

}

void swap_P(int *a,int *b){
     int tmp;
     tmp = *a;
     *a = *b;
     *b =tmp;

}

int main(){
     char *p1,*p2;
     char str1[50],str2[30];
     p1 = str1;
     p2 =str2;
     cout << "Enter a string: " << endl;
     // gets(str1);//过期函数
       if (fgets(str1,sizeof(str1),stdin) == NULL)
     {
          return(-1);
     }
     std::cout <<"befoure:"<< str1 << std::endl;
     // str1[strlen(str1)] = '\0';
     size_t len = strlen(str1);
     // 如果字符串以换行符结尾，则去掉它
     if (str1[len - 1] == '\n') {
          str1[len - 1] = '\0'; // 替换换行符为空字符
     }
     std::cout <<"after:" <<str1 << std::endl;

     cout << "Enter str2 string:"<<endl;

     // if (fgets(str2,Z_MAXLEN,stdin) == NULL)
      if (fgets(str2,sizeof(str2),stdin) == NULL)
     {
          return(-1);
     }
     


     while (*p1 !='\0')
     {
         p1++;
     }
     // *p1 = '\0'; //去掉fgets的换行符
     while (*p2 != '\0')
     {
          // *p1++ = *p2++;
          *(p1++) = *(p2++);
     }
     *p1 = '\0';

     // cout <<"The concatenated string is:"<<str1<<endl;
      cout <<"The concatenated string is:"<<endl;
      fputs(str1,stdout);

     int a;
     int &ref_a = a;//引用是只有在C++中才存在的概念，C语言是没有引用的。用是变量的别名，换句话说，就是为其起一个外号。一旦引用被初始化为一个变量，就不能再被改变为另一个变量的引用。引用不占用额外的内存空间（除了它引用的变量本身的内存）。
     a=100;
     cout<<"ref_a="<<ref_a<<endl;

     //使用引用传递参数
     int x=20;
     int y=30;
     swap(x,y);
     cout<<"x="<<x<<",y="<<y<<endl;

     //使用指针传递参数
     swap_P(&x,&y);
     cout<<"after swap_P() x="<<x<<",y="<<y<<endl;

     //整个数组作为参数传递，此种方法会引起数组拷贝，效率低，不推荐使用
     int intArr[5] = {1,2,3,4,5};
     print_arr(intArr,sizeof(intArr)/sizeof(intArr[0]));


     // 数组作为引用传递，效率高，推荐使用
     print_arr_refer(intArr,sizeof(intArr)/sizeof(intArr[0]));

     // 数组作为指针传递，效率高，推荐使用
     print_arr_p(intArr,sizeof(intArr)/sizeof(intArr[0]));

     //使用C++ 标准库中的std::vector等容器，这些容器可以方便地传递给函数，并且不需要显式地传递数组大小。
     std::vector<int> vec = {1, 2, 3, 4, 5};
     print_arr_vector(vec);

     struct PersonInfo *pPersonInfo;
     pPersonInfo = Person;
     for (int  i = 0; i < 5; i++,pPersonInfo++)
     {
          cout << pPersonInfo->index << " " << pPersonInfo->name << " " << pPersonInfo->age << endl;

     }
     

     //模板函数重载
     cout<<"min(10,20)"<<minT(10,20)<<endl;
     cout<<"min('a','b')"<<minT('a','b')<<endl;
     cout<<"min(\"hi\",\"mr\")"<<minT("hi","mr")<<endl;
     

     return 0;


}